<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
		"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<title>doh.robot Tree Test</title>

	<style>
		@import "../../../util/doh/robot/robot.css";
	</style>

	<!-- required: dojo.js -->
	<script type="text/javascript" src="../../../dojo/dojo.js"
		djConfig="isDebug: true, parseOnLoad: true"></script>

	<script type="text/javascript">
		dojo.require("dijit.robotx");

		var treeIds = ["mytree", "tree2"];

		function treeTests(){
			var that = {};

			var forceLoadChildItems = function(/*dijit._TreeNode*/inNode, /*dijit.Tree*/inTree){
				if(inTree.model.mayHaveChildren(inNode.item)){
					if(inNode.getChildren().length > 0){
						return;
					}
					var childItems = null;
					inTree.model.getChildren(inNode.item, function(items){ childItems = items; });
					inNode.setChildItems(childItems);
					childItems = null;
				}
			};

			that.testTreeItemRole = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
				if(inRoot){
					doh.is("treeitem", dijit.getWaiRole(inRoot.labelNode), inRoot.label + "[" + inTree.id + "]: aria role (treeItem)");
					//recurse
					forceLoadChildItems(inRoot, inTree);
					var children = inRoot.getChildren();
					for(var i = 0; i < children.length; i++){
						that.testTreeItemRole(children[i], inTree);
					}
				}
			};

			that.test1TreeItemExpandedState = function(/*dijit._TreeNode*/inItem, /*dijit.Tree*/inTree){
				if(inItem){
					if(inItem.isExpandable){
						var wasExpanded = inItem.isExpanded;
						inTree._expandNode(inItem);
						var nowExpanded = dijit.getWaiState(inItem.labelNode, "expanded");
						inTree._collapseNode(inItem);
						var nowCollapsed = dijit.getWaiState(inItem.labelNode, "expanded");
						if(wasExpanded){
							inTree._expandNode(inItem);
						}
						doh.is("true", nowExpanded, inItem.label + "[" + inTree.id + "]: aria state expanded=true");
						doh.is("false", nowCollapsed, inItem.label + "[" + inTree.id + "]: aria state expanded=false");
					}else{
						doh.is("", dijit.getWaiState(inItem.labelNode, "expanded"), inItem.label + "[" + inTree.id + "]: aria state expanded=false");
					}
				}
			};

			that.testTreeItemExpandedState = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
				if(inRoot){
					that.test1TreeItemExpandedState(inRoot, inTree);
					//recurse
					forceLoadChildItems(inRoot, inTree);
					var children = inRoot.getChildren();
					for(var i = 0; i < children.length; i++){
						that.testTreeItemExpandedState(children[i], inTree);
					}
				}
			};

			// Tab focus test data and functions
			var xtraParas = [];
			var expectedBlurCount = 0;
			var focusCount = 0;
			var blurCount = 0;
			var gotFocus = function(){
				focusCount++;
			};
			var lostFocus = function(){
				blurCount++;
			};
			that.focusConnect = null;
			that.blurConnect = null;

			var addTabNavFoci = function(inTree){
				var aPara = dojo.doc.createElement("p");
				dojo.attr(aPara, 'tabIndex', 0);
				aPara.innerHTML = "Tab-focussable paragraph just above " + inTree.id;
				dojo.place(aPara, inTree.domNode, "before");
				xtraParas.push(aPara);
				aPara = dojo.doc.createElement("p");
				dojo.attr(aPara, 'tabIndex', 0);
				aPara.innerHTML = "Tab-focussable paragraph just below  " + inTree.id;
				dojo.place(aPara, inTree.domNode, "after");
				xtraParas.push(aPara);
			};

			var walkTreeToLeaf = function(inTree, inRootNode, /*array, optional*/ioPath){
				var leaf = inRootNode;
				if (ioPath){ ioPath.push(inRootNode); }
				if(inRootNode.isExpandable){
					forceLoadChildItems(inRootNode, inTree);
					inTree._expandNode(inRootNode);
					var down = inRootNode.getChildren()[0];
					if(down){
						leaf = walkTreeToLeaf(inTree, down, ioPath);
					}
				}
				return(leaf);
			};

			that.tabFocusSetup = function(inTreeId, /*boolean*/ leaf){
				var tree = dijit.byId(inTreeId);
				that.collapseAllButRoot(tree);
				addTabNavFoci(tree);
				// set up focus listener machinery
				focusCount = blurCount = 0;
				var focusThing;
				if(leaf){
					focusThing = walkTreeToLeaf(tree, tree.rootNode);
				}else if(tree.showRoot){
					focusThing = tree.rootNode;
				}else{
					focusThing = tree.rootNode.getChildren()[0];
				}
				that.focusConnect = tree.connect(focusThing.labelNode, "onfocus", gotFocus);
				that.blurConnect = tree.connect(focusThing.labelNode, "onblur", lostFocus);
				tree.focusNode(focusThing);
			};

			that.tabFocusA11yTest = function(inTreeId){
				var d = new doh.Deferred();
				var tree = dijit.byId(inTreeId);
				// shift+tab away, tab back, tab away, shift+tab back
				doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
				doh.robot.keyPress(dojo.keys.TAB, 300);
				doh.robot.keyPress(dojo.keys.TAB, 300);
				doh.robot.keyPress(dojo.keys.TAB, 300, {shift:true});
				var checkTabNav = function(){
					tree.disconnect(that.focusConnect);
					tree.disconnect(that.blurConnect);
					doh.is(3, focusCount,  tree.id + ": # of times focussed");
					doh.is(2, blurCount, tree.id + ": # of times lost focus");
				};
				doh.robot.sequence(d.getTestCallback(checkTabNav), 500);
				return d;
			};

			that.tabFocusTearDown = function(){
				dojo.forEach(xtraParas, function(item){
					item.parentNode.removeChild(item);
				});
				xtraParas.length = 0;
				that.focusCount = 0;
				that.blurCount = 0;
			};

			// arrow key navigation, expand, and collapse tests.
			that.collapseAllButRoot = function(inTree){
				function collapse(node){
					if(node){
						var children = node.getChildren();
						dojo.forEach(children, function(child){
							if(child.isExpandable){
								collapse(child);
								inTree._collapseNode(child);
							}
						});
					}
				}
				if(inTree){
					collapse(inTree.rootNode);
				}
			};

			that.openConnect = null;
			that.closeConnect = null;
			var openedLabels = [];
			var closedLabels = [];

			that.a11yNavExpandCollapseSetup = function(inTreeId){
				var tree = dijit.byId(inTreeId);
				that.collapseAllButRoot(tree);
				var startingNode = tree.showRoot ? tree.rootNode : tree.rootNode.getChildren()[0];
				tree.focusNode(startingNode);
				var rootChilds = tree.rootNode.getChildren();
				// down, right (open), left (close), down, left (open)
				if(tree.showRoot){
					openedLabels[0] = { expected: rootChilds[0].label };
					openedLabels[1] = { expected: rootChilds[1].label };
				}else{
					openedLabels[0] = { expected: rootChilds[1].label };
					openedLabels[1] = { expected: rootChilds[2].label };
				}
				closedLabels[0] = openedLabels[0];
				var openIdx = 0;
				var collectOpen = function(item, node){
					openedLabels[openIdx].actual = node.label;
				};
				var collectClose = function(item, node){
					closedLabels[openIdx].actual = node.label;
					openIdx++;
				};
				that.openConnect = dojo.connect(tree, "onOpen", collectOpen);
				that.closeConnect = dojo.connect(tree, "onClose", collectClose);
			};

			that.a11yNavExpandCollapseTest = function(inTreeId){
				var d = new doh.Deferred();
				// assume (1) collapaseAllButRoot(), and (2) focus is on first visible child.
				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);		// move down one
				doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
				doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse
				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down one
				doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
				var checkKeystrokes = function(){
					for(var idx = 0; idx < openedLabels.length; idx++){
						doh.is(openedLabels[idx].expected, openedLabels[idx].actual, "onOpen");
					}
					for(idx = 0; idx < closedLabels.length; idx++){
						doh.is(closedLabels[idx].expected, closedLabels[idx].actual, "onClose");
					}
				};
				doh.robot.sequence(d.getTestCallback(checkKeystrokes), 500);
				return d;
			};

			that.a11yNavExpandCollapseTearDown = function(){
				dojo.disconnect(that.openConnect);
				dojo.disconnect(that.closeConnect);
			};

			var expectedNode;
			var actualNode;
			var arrowDownCount;
			var arrowRightCount;

			that.a11yNavToLeafSetup = function(inTreeId){
				var tree = dijit.byId(inTreeId);
				// randomly choose a top-level node to traverse.
				arrowDownCount = Math.floor(Math.random() * tree.rootNode.getChildren().length);
				var path = [];
				expectedNode = walkTreeToLeaf(tree, tree.rootNode.getChildren()[arrowDownCount], path);
				that.collapseAllButRoot(tree);
				if(tree.showRoot){
					tree.focusNode(tree.rootNode);
					arrowDownCount++;
				}else{
					tree.focusNode(tree.rootNode.getChildren()[0]);
				}
				// 1 to open root node, 2 for every non-leaf, 1 to get to the leaf
				arrowRightCount = 1 + (path.length - 2)*2 + 1;
				that.focusConnect = tree.connect(expectedNode.labelNode, "onfocus", function(evt){
					actualNode = evt.target;
				});
			};

			that.a11yNavToLeaf = function(inTreeId){
				var d = new doh.Deferred();
				var tree = dijit.byId(inTreeId);
				// assume (1) collapseAllButRoot(), and (2) focus is on a top level tree node.
				for(var i = 0; i < arrowDownCount; i++) {
					doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
				}
				for(i = 0; i < arrowRightCount; i++){
					doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);
				}
				var checkLeaf = function(){
					tree.disconnect(that.focusConnect);
					doh.is(expectedNode.labelNode, actualNode, "expected: " + expectedNode.label + ", actual: " + actualNode.innerHTML);
				};
				doh.robot.sequence(d.getTestCallback(checkLeaf), 500);
				return d;
			};

			that.lastVisibleNode = function(inTree){
				var node = inTree.rootNode;
				while(node.isExpanded){
					var c = node.getChildren();
					node = c[c.length-1];
				}
				return node;
			};

			that.a11yHomeEndKeySetup = function(inTreeId, inKey){
				// put focus on an random leaf.
				var tree = dijit.byId(inTreeId);
				that.collapseAllButRoot(tree);
				var topLvl = Math.floor(Math.random() * tree.rootNode.getChildren().length);
				var leaf = walkTreeToLeaf(tree, tree.rootNode.getChildren()[topLvl]);
				tree.focusNode(leaf);
				// determine the expected/actual home.
				if(inKey == dojo.keys.HOME){
					expectedNode = ( tree.showRoot ? tree.rootNode : tree.rootNode.getChildren()[0] );
				}else{
					expectedNode = that.lastVisibleNode(tree);
				}
				focusConnect = tree.connect(expectedNode.labelNode, "onfocus", function(evt){
					actualNode = evt.target;
				});
			};

			that.a11yHomeEndKeyTest = function(inTreeId, inKey){
				var d = new doh.Deferred();
				var tree = dijit.byId(inTreeId);
				doh.robot.keyPress(inKey, 300);
				var checkAtHomeEnd = function(){
					tree.disconnect(focusConnect);
					doh.is(expectedNode.label, actualNode.innerHTML);
				}
				doh.robot.sequence(d.getTestCallback(checkAtHomeEnd), 500);
				return d;
			};

			return that;
		}

		dojo.addOnLoad(function(){
			doh.robot.initRobot('../test_Tree.html');
			var treeTest = treeTests();

			// aria role and properties tests.
			doh.register("a11yAria",
			[
				function ariaTreeRole(){
					for(i=0; i<treeIds.length; i++){
						var tree = dijit.byId(treeIds[i]);
						doh.is("tree", dijit.getWaiRole(tree.domNode), tree.id + ": aria role (tree)");
					}
				},

				function ariaTreeStateExpanded(){
					for(i=0; i<treeIds.length; i++){
						var tree = dijit.byId(treeIds[i]);
						var wasExpanded = tree.rootNode.isExpanded;
						tree.rootNode.expand();
						var nowExpanded = dijit.getWaiState(tree.domNode, "expanded");
						tree.rootNode.collapse();
						var nowCollapsed = dijit.getWaiState(tree.domNode, "expanded");
						if(wasExpanded){
							tree.rootNode.expand();
						}
						doh.is("true", nowExpanded, tree.id + ": aria state expanded=true");
						doh.is("false", nowCollapsed, tree.id + ": aria state expanded=false ");
					}
				},

				function ariaTreeItemRole(){
					for(i=0; i<treeIds.length; i++){
						var tree = dijit.byId(treeIds[i]);
						treeTest.testTreeItemRole(tree.rootNode, tree);
					}
				},

				function ariaTreeItemStateExpanded(){
					for(i=0; i<treeIds.length; i++){
						var tree = dijit.byId(treeIds[i]);
						treeTest.testTreeItemExpandedState(tree.rootNode, tree);
					}
				}
			]);

			// Keyboard focus robot tests
			doh.register("a11y tab navigation",
			[
				{
					name:"mytreeTabFocusTest",
					timeout:4000,
					setUp:function(){
						treeTest.tabFocusSetup('mytree', false);
					},
					runTest:function(){
						return treeTest.tabFocusA11yTest('mytree');
					},
					tearDown:function(){
						treeTest.tabFocusTearDown();
					}
				},
				{
					name:"tree2TabFocusTest",
					timeout:4000,
					setUp:function(){
						treeTest.tabFocusSetup('tree2');
					},
					runTest:function(){
						return treeTest.tabFocusA11yTest('tree2', false);
					},
					tearDown:function(){
						treeTest.tabFocusTearDown();
					}
				},
				{
					name:"mytreeExpandedTabFocusTest",
					timeout:4000,
					setUp:function(){
						treeTest.tabFocusSetup('mytree', true);
					},
					runTest:function(){
						return treeTest.tabFocusA11yTest('mytree');
					},
					tearDown:function(){
						treeTest.tabFocusTearDown();
					}
				},
				{
					name:"tree2ExpandedTabFocusTest",
					timeout:4000,
					setUp:function(){
						treeTest.tabFocusSetup('tree2', true);
					},
					runTest:function(){
						return treeTest.tabFocusA11yTest('tree2');
					},
					tearDown:function(){
						treeTest.tabFocusTearDown();
					}
				}
			]);

			// Keyboard navigate/expand/collapse robot tests (arrow keys, and home/end)
			doh.register("keyboard arrow navigation/expand/collapse",
			[
				{
					name:"mytreeNavExpandCollpaseA11y",
					timeout:4000,
					setUp:function(){
						treeTest.a11yNavExpandCollapseSetup('mytree');
					},
					runTest:function(){
						return treeTest.a11yNavExpandCollapseTest('mytree');
					},
					tearDown: function(){
						treeTest.a11yNavExpandCollapseTearDown();
					}
				},
				{
					name:"tree2NavExpandCollpaseA11y",
					timeout:4000,
					setUp:function(){
						treeTest.a11yNavExpandCollapseSetup('tree2');
					},
					runTest:function(){
						return treeTest.a11yNavExpandCollapseTest('tree2');
					},
					tearDown: function(){
						treeTest.a11yNavExpandCollapseTearDown();
					}
				},
				{
					name:"mytreeNavToLeaf",
					timeout:4000,
					setUp:function(){
						treeTest.a11yNavToLeafSetup('mytree');
					},
					runTest:function(){
						return treeTest.a11yNavToLeaf('mytree');
					}
				},
				{
					name:"tree2NavToLeaf",
					timeout:4000,
					setUp:function(){
						treeTest.a11yNavToLeafSetup('tree2');
					},
					runTest:function(){
						return treeTest.a11yNavToLeaf('tree2');
					}
				},
				{
					name:"mytreeNavToHome",
					timeout:4000,
					setUp:function(){
						treeTest.a11yHomeEndKeySetup('mytree', dojo.keys.HOME);
					},
					runTest:function(){
						return treeTest.a11yHomeEndKeyTest('mytree', dojo.keys.HOME);
					}
				},
				{
					name:"mytreeNavToEnd",
					timeout:4000,
					setUp:function(){
						treeTest.a11yHomeEndKeySetup('mytree', dojo.keys.END);
					},
					runTest:function(){
						return treeTest.a11yHomeEndKeyTest('mytree', dojo.keys.END);
					}
				},
				{
					name:"tree2NavToHome",
					timeout:4000,
					setUp:function(){
						treeTest.a11yHomeEndKeySetup('tree2', dojo.keys.HOME);
					},
					runTest:function(){
						return treeTest.a11yHomeEndKeyTest('tree2', dojo.keys.HOME);
					}
				},
				{
					name:"tree2NavToEnd",
					timeout:4000,
					setUp:function(){
						treeTest.a11yHomeEndKeySetup('tree2', dojo.keys.END);
					},
					runTest:function(){
						return treeTest.a11yHomeEndKeyTest('tree2', dojo.keys.END);
					}
				}
			]);

			// Test for typing "a" to navigate to nodes that start with "a", etc.
			doh.register("keyboard search tests",
			[
				{
					name:"Setup tree",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						var tree = dijit.byId("mytree");

						// Close all tree nodes except for Asia and Oceania
						dojo.forEach(tree.rootNode.getChildren(), function(child, idx){
							if(child.label == "Asia" || child.label == "Oceania"){
								console.log("expanding " + child.label);
								if(!child.isExpanded){
									tree._expandNode(child);
								}
							}else{
								console.log("collapsing " + child.label);
								if(child.isExpanded){
									tree._collapseNode(child);
								}
							}
						});

						doh.robot.sequence(d.getTestCallback(function(){
							// Just waiting for animation to finish...
						}), 500);

						return d;
					}
				},
				{
					name:"Focus on Continents",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						var tree = dijit.byId("mytree");
						tree.focusNode(tree.rootNode);

						doh.robot.sequence(d.getTestCallback(function(){
							var focus = dojo.global.dijit._curFocus;
							doh.t(tree.rootNode.labelNode, "focused on continents");
						}), 500);

						return d;
					}
				},
				{
					name:"First 'A' key goes to Africa",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						// From Continents node, press "A".   Should go to Africa.
						doh.robot.keyPress("a", 100);
						doh.robot.sequence(d.getTestCallback(function(){
							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
							doh.t(focus, "there is a focused widget");
							doh.is("Africa", focus.label);
						}), 500);

						return d;
					}
				},
				{
					name:"Second 'A' key goes to Asia",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						// From Africa node, press "A" again.   Should go to Asia.
						doh.robot.keyPress("a", 100);
						doh.robot.sequence(d.getTestCallback(function(){
							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
							doh.t(focus, "there is a focused widget");
							doh.is("Asia", focus.label);
						}), 500);

						return d;
					}
				},
				{
					name:"Third 'A' key goes to Australia (nested node)",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						var oceania = dijit.byId("mytree").rootNode.getChildren()[2];
						doh.t(oceania, "found Oceania node");
						doh.t(oceania.isExpanded, "Oceania node is expanded");

						doh.robot.keyPress("a", 100);
						doh.robot.sequence(d.getTestCallback(function(){
							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
							doh.t(focus, "there is a focused widget");
							doh.is("Australia", focus.label);
						}), 500);

						return d;
					}
				},
				{
					name:"Fourth 'A' key loops back to Africa",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						doh.robot.keyPress("a", 100);
						doh.robot.sequence(d.getTestCallback(function(){
							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
							doh.t(focus, "there is a focused widget");
							doh.is("Africa", focus.label);
						}), 500);

						return d;
					}
				},
				{
					name:"multi-key navigation",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						// Skip over China and go to Continents
						doh.robot.typeKeys("co", 100);
						doh.robot.sequence(d.getTestCallback(function(){
							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
							doh.t(focus, "there is a focused widget");
							doh.is("Continents", focus.label);
						}), 500);

						return d;
					}
				},
				{
					name:"multi-key navigation",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						// By typing AS should skip over Africa and go to Asia
						doh.robot.typeKeys("as", 100);
						doh.robot.sequence(d.getTestCallback(function(){
							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
							doh.t(focus, "there is a focused widget");
							doh.is("Asia", focus.label);
						}), 500);

						return d;
					}
				},
				{
					name:"multi-key navigation clears",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						// After the 500ms delay from above, typing a new character should
						// start a new search
						doh.robot.typeKeys("n", 100);
						doh.robot.sequence(d.getTestCallback(function(){
							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
							doh.t(focus, "there is a focused widget");
							doh.is("North America", focus.label);
						}), 500);

						return d;
					}
				}
			]);

			doh.register("selection and focus",
			[
				{
					name:"select Africa",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						var tree = dijit.byId("mytree");

						doh.robot.keyPress(dojo.keys.HOME, 300);			// go to Continents
						doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse tree, if it's open
						doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down to Africa
						doh.robot.keyPress(dojo.keys.ENTER, 300);			// select it
						
						doh.robot.sequence(d.getTestCallback(function(){
							doh.is("Africa", tree.lastFocused.label, "Africa is focused");

							var item = tree.get("selectedItem"),
								label = tree.model.getLabel(item);
							doh.is("Africa", label, "Africa is selected");
						}), 500);

						return d;
					}
				},

				{
					name:"focus Asia",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						var tree = dijit.byId("mytree");

						if(tree.lastFocused.isExpanded){
							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse tree, if it's open
						}
						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down to Asia
						
						doh.robot.sequence(d.getTestCallback(function(){
							doh.is("Asia", tree.lastFocused.label, "Asia is focused");

							var item = tree.get("selectedItem"),
								label = tree.model.getLabel(item);
							doh.is("Africa", label, "but Africa is still selected");
						}), 500);

						return d;
					}
				},

				{
					name:"select Asia",
					timeout:4000,
					runTest:function(){
						var d = new doh.Deferred();

						var tree = dijit.byId("mytree");

						doh.robot.keyPress(dojo.keys.ENTER, 300);			// select it
						
						doh.robot.sequence(d.getTestCallback(function(){
							var item = tree.get("selectedItem"),
								label = tree.model.getLabel(item);
							doh.is("Asia", label, "after ENTER focus shifted from Africa to Asia");
						}), 500);

						return d;
					}
				}
			]);

			doh.run();
		});

	</script>
</head>
</html>

